<?php
#
# dmBridge: a data access framework for CONTENTdm(R)
#
# Copyright © 2009, 2010, 2011 Board of Regents of the Nevada System of Higher
# Education, on behalf of the University of Nevada, Las Vegas
#

/**
 * <p>An class consisting of helper methods to assist in creating web page
 * templates. These methods are specific to object view and are neither
 * guaranteed nor expected to work in any other view.</p>
 *
 * <p>This class was called ObjectDraw in dmBridge 1.x.</p>
 *
 * @author Alex Dolski <alex.dolski@unlv.edu>
 * @license http://www.opensource.org/licenses/mit-license.php
 */
class DMObjectTemplateHelper extends DMGenericTemplateHelper
implements DMTemplateHelper {

	/**
	 * @return string HTML &lt;span&gt; element
	 * @since 0.1
	 */
	public function getHtmlAddFavoriteButton() {
		$obj = $this->getView()->getObject();
		$collection = $obj->getCollection();
		$alias = $collection->getAlias();
		$alias = ($alias == "/dmdefault") ? "" : $alias;

		if (!$obj->isFavorite()) {
			return sprintf('<form method="post" action="%s">
					<p class="dmAddFavorite">
						<input type="hidden" name="alias" value="%s">
						<input type="hidden" name="ptr" value="%d">
						<input type="submit" value="Add To Favorites">
					</p>
				</form>',
				DMInternalURI::getURIWithParams(
						sprintf("objects%s/favorites", $alias)),
				DMString::websafe($obj->getCollection()->getAlias()),
				$obj->getPtr());
		}

		return sprintf('<span class="dmAddFavoriteText">This object is in
					<a href="%s">your favorites</a>.
				</span>',
				DMInternalURI::getURIWithParams(sprintf("objects%s/favorites", $alias)));
	}

	/**
	 * <p>Returns a hyperlinked ordered list of each of the pages of the current
	 * object wrapped in &lt;li&gt; elements. The &lt;li&gt;
	 * element of the current page is of class <code>dmCurrentPage</code>, and
	 * the &lt;ol&gt; element itself is of class <code>dmChildLinks</code>.</p>
	 *
	 * <p>For compound objects with more than a few pages, you may want to put
	 * this list inside of a div that has a fixed CSS height, and overflow set
	 * to &quot;auto&quot;, which will cause it to appear with a scrollbar,
	 * like an iframe.</p>
	 *
	 * @param Boolean thumbs Whether or not to append thumbnails to the pages
	 * @return string (X)HTML ordered list element
	 * @see getHtmlChildLinksAsPulldown()
	 * @since 0.1
	 */
	public function getHtmlChildLinksAsList($thumbs = false) {
		$obj = $this->getView()->getObject();
		$obj = ($obj->isChild()) ? $obj->getParent() : $obj;

		$links = "";
		foreach ($obj->getChildren() as $child) {
			$selected = ($child->getPtr() == $obj->getPtr())
				? 'class="dmCurrentPage"' : null;

			$links .= sprintf('<li %s><div>', $selected);

			if ($thumbs) {
				$links .= sprintf(
					'<a href="%s">
						<img class="dmThumbnail" src="%s" alt="Page thumbnail">
					</a>',
					DMString::websafe($child->getURI()),
					DMString::websafe($child->getThumbnailURL()));
			}
			$links .= sprintf('<a href="%s">%s</a></div></li>',
				DMString::websafe($child->getURI()),
				DMString::websafe($child->getTitle()));
		}
		return '<ol class="dmChildLinks">' . $links . '</ol>';
	}

	/**
	 * <p>Returns a complete HTML form with a pulldown menu consisting of
	 * each of the pages of the current object as &lt;option&gt; elements.</p>
	 *
	 * <p>Note: This method requires that JavaScript be enabled in the browser.
	 * Using <code>drawChildLinksAsList()</code> instead is preferred for
	 * usability.</p>
	 *
	 * @return string HTML form element
	 * @see getHtmlChildLinksAsList()
	 * @since 0.1
	 */
	public function getHtmlChildLinksAsPulldown() {
		$obj = $this->getView()->getObject();
		$obj = ($obj->isChild()) ? $obj->getParent() : $obj;

		$dxml = new DMDOMDocument("1.0", "utf-8");
		$dxml->loadXML("<form/>");
		$dxml->documentElement->setAttribute("method", "get");
		$dxml->documentElement->setAttribute(
			'action', trim(dirname($_SERVER['PHP_SELF']), "/"));

		$sel = $dxml->createElement("select");
		$sel->setAttribute("onchange",
			sprintf("window.location = '/%s/%s/' + this.value",
				trim(dirname($_SERVER['PHP_SELF']), '/'),
				trim($obj->getCollection()->getAlias(), "/")));

		foreach ($obj->getChildren() as $c) {
			$opt = $dxml->createElement(
				"option", DMString::websafe($c->getMetadata("title")));
			$opt->setAttribute("value", $c->getPtr());
			if ($c->getPtr() == $obj->getPtr()) {
				$opt->setAttribute("selected", "selected");
			}
			$sel->appendChild($opt);
		}

		$dxml->documentElement->appendChild($sel);
		return $dxml->saveHTML($dxml->documentElement);
	}

	/**
	 * Draws the HTML for the comments section. The HTML structure will vary
	 * depending on whether the object has any comments, and whether commenting
	 * is enabled.
	 *
	 * @return string HTML &lt;form&gt; element
	 * @since 0.1
	 */
	public function getHtmlCommentsSection() {
		$obj = $this->getView()->getObject();

		try {
			$are_comments = $obj->hasComments();

			$obj = ($obj->isChild()) ? $obj->getParent() : $obj;

			if ($are_comments) {
				$comments = "";
				foreach (DMDataStoreFactory::getDataStore()
						->getApprovedCommentsForObject($obj, 1, 1000) as $c) {
					$comments .= sprintf('<tr><th class="dmCommentAuthor">%s</th>',
						DMString::websafe($c->getName()));
					$comments .= sprintf('<th class="dmCommentDate">%s</th></tr>',
						$c->getTimestamp()->format('Y-m-d @ h:i A'));
					$comments .= sprintf('<tr><td colspan="2" class="dmCommentBody">%s</td></tr>',
						nl2br(DMString::websafe($c->getValue())));
				}
				$comments = '<table class="dmComments" cellspacing="0" cellpadding="0"
					border="0">' . $comments . '</table>';
			} else if (!DMHTTPRequest::getCurrent()->getSession()->hasCommentedOnObject($obj)) {
				$comments = '<p>There are no comments yet.
					Be the first to comment below!</p>';
			} else {
				$comments = '<p>There are no approved comments yet.</p>';
			}
		} catch (DMException $e) {
			return '<p>Sorry, we seem to be having some issues with our commenting
				system at the moment. Come back soon!</p>';
		}

		if (DMHTTPRequest::getCurrent()->getSession()->hasCommentedOnObject($obj)) {
			return '<p>Your comment has been received and is pending review.</p>'
				. $comments;
		}

		$this->getView()->getCommentForm()->getFieldByName("alias")->setValue(
				$obj->getCollection()->getAlias());
		$this->getView()->getCommentForm()->getFieldByName("ptr")->setValue(
				$obj->getPtr());
		$this->getView()->getCommentForm()->getFieldByName("response")
				->setValue(null);
		$a = DMAbstractForm::getCaptchaOperands();

		if (!DMConfigXML::getInstance()->isCommentingEnabled()) {
			return $comments;
		}

		return $comments . sprintf(
			'<form method="post" action="">
				<fieldset>
					<legend>Comment on this object</legend>
					<ol>
						<li><label for="dmCommentName">Your Name:</label>%s</li>
						<li><label for="dmCommentEmail">Your E-mail:</label>%s</li>
						<li>
							<label for="dmCommentText">Your Comment:</label>
							%s
							<div style="display:none">
								<label for="dmFauxComment">Leave this field
									blank:</label>
								<textarea name="fauxcomment" id="dmFauxComment"
									rows="0" cols="0"></textarea>
							</div>
						</li>
						<li>
							%s%s%s
							<label id="dmCaptchaChallenge">What\'s %d + %d?</label>
							%s
						</li>
						<li>
							<input type="hidden" name="action" value="comment">
							<input type="submit" value="Submit" class="dmSubmit">
						</li>
					</ol>
				</fieldset>
			</form>',
			$this->getView()->getCommentForm()
				->getFieldByName("name")->getHTMLTag(),
			$this->getView()->getCommentForm()
				->getFieldByName("email")->getHTMLTag(),
			$this->getView()->getCommentForm()
				->getFieldByName("text")->getHTMLTag(),
			$this->getView()->getCommentForm()
				->getFieldByName("alias")->getHTMLTag(),
			$this->getView()->getCommentForm()
				->getFieldByName("ptr")->getHTMLTag(),
			$this->getView()->getCommentForm()
				->getFieldByName("answer")->getHTMLTag(),
			$a[0],
			$a[1],
			$this->getView()->getCommentForm()
				->getFieldByName("response")->getHTMLTag()
		);
	}

	/**
	 * @param string button_text
	 * @return An HTML form for searching the compound object, or false if
	 * the object is not a compound object; has no full text; or has no pages.
	 * @since 0.1
	 */
	public function getHtmlCompoundObjectSearchForm(
			$button_text = "Search Object Text") {
		$obj = $this->getView()->getObject();
		if (!$obj instanceof DMObject) {
			return null;
		}
		if (!$obj->getFullText()) {
			return null;
		}
		if (!$obj->isChild() && !$obj->hasChildren()) {
			return null;
		}

		$action = DMInternalURI::getURIWithParams(
			sprintf("%s/%d/search",
				$obj->getCollection()->getAlias(),
				$obj->getPtr()));

		$term = DMHTTPRequest::getCurrent()->getURI()->getQueryValue("term");
		return sprintf(
			'<form method="get" action="%s">
				<p>
					<input type="text" name="term" value="%s">
					<input type="submit" value="%s">
				</p>
			</form>',
			$action,
			(strlen($term) > 0)
				? DMString::websafe(substr($term, 0, 100)) : "",
			DMString::websafe($button_text));
	}

	/**
	 * @param string separator
	 * @return string
	 * @since 0.1
	 */
	public function getHtmlCompoundObjectPageNumbersInSearchResultsAsString(
			$separator = ", ") {
		$query = $this->getView()->getQuery();
		$current_obj = $this->getView()->getObject();

		if (!$query instanceof DMObjectQuery) {
			return false;
		}
		$pages = array();
		foreach ($query->getSearchResults() as $obj) {
			if (!$obj->isChild()) {
				continue; // shouldn't ever happen...
			}
			if ($obj->getPtr() == $current_obj->getPtr()) {
				$pages[] = $obj->getPage();
			} else {
				$pages[] = sprintf('<a href="%s&term=%s">%d</a>',
					DMString::websafe(
							$obj->getURI(DMBridgeComponent::TemplateEngine)),
					$query->getPredicates(0),
					$obj->getPage());
			}
		}
		return implode($separator, array_unique($pages));
	}

	/**
	 * Provides navigation links between compound object pages.
	 *
	 * @param string separator
	 * @param string prev_page_link
	 * @param string next_page_link
	 * @return string
	 * @since 0.1
	 */
	public function getHtmlCompoundPageFlipLinks(
			$separator = " | ",
			$prev_page_link = "< Previous Page",
			$next_page_link = "Next Page >") {
		$obj = $this->getView()->getObject();
		$obj = ($obj->isChild()) ? $obj->getParent() : $obj;

		$pages = array();
		$children = $obj->getChildren();
		$count = count($children);
		for ($i = 0; $i < $count; $i++) {
			if ($obj->getPtr() <> $children[$i]->getPtr()) {
				continue;
			}

			if (array_key_exists($i-1, $children)) {
				$pages[] = sprintf('<a href="%s">%s</a>',
					DMString::websafe(
							$children[$i-1]->getURI(DMBridgeComponent::TemplateEngine)),
					DMString::websafe($prev_page_link));
			} else {
				$pages[] = DMString::websafe($prev_page_link);
			}

			if (array_key_exists($i+1, $children)) {
				$pages[] = sprintf('<a href="%s">%s</a>',
					DMString::websafe(
							$children[$i+1]->getURI(DMBridgeComponent::TemplateEngine)),
					DMString::websafe($next_page_link));
			} else {
				$pages[] = DMString::websafe($next_page_link);
			}

			break;
		}
		return implode($separator, $pages);
	}

	/**
	 * @param DMObject obj
	 * @param array resolutions Indexed array of maximum pixel resolutions of
	 * the longest side of the image
	 * @param string separator
	 * @return Series of HTML anchor tags of class "dmDownloadLink" if $obj is
	 * an image object; or an empty string if not
	 * @since 0.1
	 */
	public function getHtmlDownloadImageLink(
			$resolutions = array(800, 1200, 1600), $separator = " | ") {
		asort($resolutions);
		$links = array();
		foreach ($resolutions as $r) {
			$links[] = sprintf('<a class="dmDownloadLink" href="%s">%d</a>',
					DMString::websafe($this->getView()->getObject()->getImageURL($r, $r)),
					$r);
		}
		return implode($separator, $links);
	}

	/**
	 * Outputs text with highlighted terms in &lt;span&gt; elements with class
	 * &quot;dmHighlightedTerm&quot;. Simply apply the CSS background-color
	 * property - or whatever other properties you like - to this class.
	 *
	 * @return string HTML-escaped string
	 * @since 0.1
	 */
	public function getHtmlHighlightedFullText() {
		$obj = $this->getView()->getObject();
		$allow = array(" ", "-");
		$term = DMHTTPRequest::getCurrent()->getURI()->getQueryValue("term");
		$needle = DMString::paranoid(
			strtolower(substr($term, 0, 100)),
			$allow);
		$haystack = DMString::websafe($obj->getFullText());
		return DMString::highlight($needle, $haystack);
	}

	/**
	 * Returns object metadata in an HTML definition list, which is probably
	 * the most semantic way to mark it up using the HTML element set. This
	 * list can be styled with CSS. Fields that are set as both searchable and
	 * controlled in CONTENTdm&reg; are automatically hyperlinked to searches.
	 *
	 * @param string ctrld_term_separator Character or character sequence that
	 * should separate controlled terms
	 * @param [string|null|false] link_ctrld_terms_to_view One of 'grid',
	 * 'list', 'tile', null (use default view), or false (don't link them)
	 * @param Boolean add_link_to_feed
	 * @param Boolean omit_title Whether to omit the title field
	 * @param DMObject An optional DMObject whose metadata to display. If null
	 * or not provided, the current DMObject's metadata is displayed.
	 * @param hyperlink_urls Whether to add &lt;a&gt; tags around URLs in
	 * metadata
	 * @return string
	 * @since 0.1
	 */
	public function getHtmlMetadataAsDL(
			$ctrld_term_separator = null,
			$link_ctrld_terms_to_view = null,
			$add_link_to_feed = true,
			$omit_title = false,
			DMObject $object = null,
			$hyperlink_urls = true) {

		$dxml = new DMDOMDocument("1.0", "utf-8");
		$dxml->loadXML("<dl/>");
		$dxml->documentElement->setAttribute("class", "dmMetadataList");

		if (!$object instanceof DMObject) {
			$object = $this->getView()->getObject();
		}

		foreach ($object->getMetadata() as $field) {
			if (!$field instanceof DMDCElement) {
				continue;
			}
			if ($field->isHidden()) {
				continue; // ignore hidden fields
			}
			if ($field->getNick() == "full") {
				continue; // ignore fulltext field
			}
			if (strlen($field->getValue()) < 1) {
				continue; // ignore empty fields
			}
			if ($omit_title && $field->getNick() == "title") {
				continue;
			}

			$ul = null;
			if ($field->isControlled() && $field->isSearchable()) {
				$ul = $dxml->createElement("ul");
				$terms = explode("; ", $field->getValue());

				$q = array();
				foreach ($terms as $term) {
					$li = $dxml->createElement("li");
					if ($link_ctrld_terms_to_view !== false) {
						$q = array(
							'CISOBOX1' => rtrim(trim($term), ";"),
							'CISOFIELD1' => 'CISOSEARCHALL',
							'CISOOP1' => 'exact',
							'CISOROOT' => DMString::websafe(
								$object->getCollection()->getAlias()),
							'view' => $link_ctrld_terms_to_view
						);
						$a = $dxml->createElement("a",
							DMString::websafe(ltrim(rtrim($term, ";"))));
						$alias = $object->getCollection()->getAlias();
						$alias = ($alias == "/dmdefault") ? "" : $alias;
						$a->setAttribute("href",
							DMInternalURI::getURIWithParams(
									"objects" . $object->getCollection()->getAlias(),
									$q));
						$li->appendChild($a);
					} else {
						$li->nodeValue = DMString::websafe(ltrim(rtrim($term, ";")));
					}

					if ($add_link_to_feed) {
						$a = $dxml->createElement("a", "(feed)");
						$a->setAttribute("title",
							"Subscribe to a search for this term");
						$a->setAttribute("class", "dmFeedLink");
						$a->setAttribute("href",
							DMInternalURI::getURIWithParams(
									"objects" . $object->getCollection()->getAlias(),
									$q, "atom"));
						$li->appendChild($a);
					}
					$ul->appendChild($li);
				} // foreach
			} // if

			$dxml->documentElement->appendChild(
				$dxml->createElement("dt",
						DMString::websafe($field->getName())));

			$dd = $dxml->createElement("dd");
			if ($ul instanceof DOMElement) {
				$dd->appendChild($ul);
			} else {
				if ($hyperlink_urls) {
					$dd->appendChild(DMString::hyperlink(
							DMString::websafe($field->getValue()), $dxml));
				} else {
					$dd->nodeValue = DMString::websafe($field->getValue());
				}
			}
			$dxml->documentElement->appendChild($dd);
		} // foreach
		return $dxml->saveHTML($dxml->documentElement);
	}

	/**
	 * Returns object metadata as HTML meta tags.
	 *
	 * @return string
	 * @since 0.3
	 */
	public function getHtmlMetadataAsMetaTags() {
		$data = array();
		foreach ($this->getView()->getObject()->getMetadata() as $field) {
			if (!$field instanceof DMDCElement) {
				continue;
			}
			if ($field->isHidden()) {
				continue; // ignore hidden fields
			}
			if ($field->getNick() == "full") {
				continue; // ignore fulltext field
			}
			if (strlen($field->getValue()) < 1) {
				continue; // ignore empty fields
			}
			$data[] = sprintf(
				'<meta name="DC.%s" content="%s">',
				DMString::websafe($field->getDCName()),
				DMString::websafe($field->getValue())
			);
		}
		return implode("\n", $data);
	}

	/**
	 * @param string separator
	 * @param string prev_text
	 * @param string next_text
	 * @return string A set of HTML anchor elements separated by the $separator
	 * string.
	 * @since 0.1
	 */
	public function getHtmlPreviousNextLinks(
			$separator = " | ", $prev_text = "< Previous",
			$next_text = "Next >") {
		$view = $this->getView();
		$prev_view = $view->getViewForPreviousObject();
		$next_view = $view->getViewForNextObject();
		$prev_url = $prev_view ? $prev_view->getURI() : null;
		$next_url = $next_view ? $next_view->getURI() : null;
		$results_url = $view->getResultsView()
				? $view->getResultsView()->getURI() : null;
		// display appropriate "Back To..." text
		$results_text = "Back To Results";
		if ($results_url) {
			$params = $results_url->getParamComponents();
			if (count($params)) {
				if ($params[count($params) - 1] == "favorites") {
					$results_text = "Back To Favorites";
				}
			}
		}

		$links = array();
		if ($prev_url != $results_url && $prev_url) {
			$links[] = sprintf('<a href="%s">%s</a>',
				DMString::websafe($prev_url), DMString::websafe($prev_text));
		}
		$links[] = sprintf('<a href="%s">%s</a>',
			DMString::websafe($results_url), DMString::websafe($results_text));
		if ($next_url != $results_url && $next_url) {
			$links[] = sprintf('<a href="%s">%s</a>',
				DMString::websafe($next_url), DMString::websafe($next_text));
		}
		return implode($separator, $links);
	}

	/**
	 * @param int min
	 * @param int max
	 * @param float multiple_of
	 * @param int decimal_places Ratings will be rounded to this many decimal
	 * places for display
	 * @return string HTML form element
	 * @since 0.1
	 */
	public function getHtmlRatingsSection($min, $max, $multiple_of,
			$decimal_places = 2) {
		if (!DMConfigXML::getInstance()->isRatingEnabled()) {
			return "<!-- Rating section not inserted, as rating is
				disabled. -->";
		}

		$ds = DMDataStoreFactory::getDataStore();
		$obj = $this->getView()->getObject();
		$obj = ($obj->isChild()) ? $obj->getParent() : $obj;

		$ratings = "";
		$num_ratings = $ds->getNumRatingsForObject($obj);
		if ($num_ratings) {
			$ratings = sprintf('<h4>Rating: %s / %d (%d ratings)</h4>',
				round($obj->getRating($max), $decimal_places),
				$max,
				$num_ratings);
		}

		if (DMHTTPRequest::getCurrent()->getSession()->hasRatedObject($obj)) {
			return $ratings;
		}
		$radios = "";
		foreach (range($min, $max, $multiple_of) as $i) {
			$radios .= sprintf('<input type="radio" name="value"
					value="%d" id="dmRatingValue%d" class="dmRatingValue">
				<label for="dmRatingValue%d">%d</label>',
				$i, $i, $i, $i);
		}
		return sprintf('<form method="post" action="">
				<div style="display:none">
					<label for="dmFauxRating">Leave this field blank:</label>
					<input type="text" name="fauxrating" id="dmFauxRating">
				</div>
				%s
				<p>%s
					<input type="hidden" name="max" value="%d">
					<input type="hidden" name="action" value="rate">
					<input type="submit" value="Rate It" class="dmRateIt">
				</p>
			</form>',
			$ratings,
			$radios,
			$max);
	}

	/**
	 * Returns an ordered list containing objects from the most recently viewed
	 * results list.
	 *
	 * @param Boolean thumbs Whether or not to display object thumbnails
	 * @param int max If larger than the number of results appearing on the
	 * last results view page, that number will be used instead
	 * @return string HTML ordered list
	 * @since 0.3
	 */
	public function getHtmlResultsAsUL($thumbs = false, $max = 5) {
		$obj = $this->getView()->getObject();
		$obj = ($obj->isChild()) ? $obj->getParent() : $obj;

		$dxml = new DMDOMDocument("1.0", "utf-8");
		$dxml->loadXML("<ol/>");

		$rv = DMHTTPRequest::getCurrent()->getSession()->getResultsView();
		$results = array();
		if ($rv) {
			$results = $rv->getQuery()->getSearchResults();
		}

		// slice results array according to the current object being viewed
		$count = count($results);
		$current_alias = $current_ptr = null;
		for ($i = 0; $i < $count; $i++) {
			if ((string) $results[$i] == (string) $obj) {
				$current_alias = $results[$i]->getCollection()->getAlias();
				$current_ptr = $results[$i]->getPtr();
				break;
			}
		}
		$slice = $i - floor($max / 2);
		if ($slice < 0) $slice = 0;
		$results = array_slice($results, $slice, $max);

		// assemble html
		foreach ($results as $obj) {
			$a = $dxml->createElement("a");
			$a->setAttribute("href",
					$obj->getURI(DMBridgeComponent::TemplateEngine));

			if ($thumbs) {
				$img = $dxml->createElement("img");
				$img->setAttribute("class", "dmThumbnail");
				$img->setAttribute("src", $obj->getThumbURL());
				$img->setAttribute("alt", "Result thumbnail");
				$a->appendChild($img);
			}

			$text = $dxml->createTextNode(
				$obj->getField("title")->getValue());
			$a->appendChild($text);

			$li = $dxml->createElement("li");
			if ($obj->getCollection()->getAlias() == $current_alias
					&& $obj->getPtr() == $current_ptr) {
				$li->setAttribute("class", "dmCurrentResult");
			}
			$li->appendChild($a);

			$dxml->documentElement->appendChild($li);
		}
		$dxml->formatOutput = true;
		return $dxml->saveHTML($dxml->documentElement);
	}

	/**
	 * @return string HTML form element, or an HTML comment if a data store
	 * is not available
	 * @since 0.3
	 */
	public function getHtmlTaggingSection() {
		if (!DMConfigXML::getInstance()->isTaggingEnabled()) {
			return "<!-- Tagging section not inserted, as tagging is
				disabled. -->";
		}

		$obj = $this->getView()->getObject();
		$this->getView()->getTagForm()->getFieldByName("alias")
				->setValue($obj->getCollection()->getAlias());
		$this->getView()->getTagForm()->getFieldByName("ptr")
				->setValue($obj->getPtr());

		return sprintf('<form method="post" action="">
				%s%s%s%s
				<input type="hidden" name="action" value="tag">
				<input type="submit" value="Add Tag">
			</form>',
			$this->getView()->getTagForm()
				->getFieldByName("value")->getHTMLTag(),
			$this->getView()->getTagForm()
				->getFieldByName("alias")->getHTMLTag(),
			$this->getView()->getTagForm()
				->getFieldByName("ptr")->getHTMLTag(),
			$this->getView()->getTagForm()
				->getFieldByName("fauxtag")->getHTMLTag(),
			DMString::websafe(DMHTTPRequest::getCurrent()->getURI()->getParams()));
	}

	/**
	 * @param int width Width override (normally, width should be set in the
	 * Control Panel)
	 * @param int height Height override (normally, height should be set in the
	 * Control Panel)
	 * @param bool js Whether to include required JavaScript code. If false,
	 * you must manually include the necessary code in the template.
	 * @return string HTML tag
	 * @since 0.1
	 * @deprecated The <code>js</code> parameter is deprecated. Please avoid
	 * using it.
	 */
	public function getHtmlViewer($width = null, $height = null, $js = true) {
		$obj = $this->getView()->getObject();
		if ($obj->isCompound() && $obj->getChild(0) instanceof DMObject) {
			$obj = $obj->getChild(0);
		}
		try {
			$viewer = $obj->getViewer($width, $height);
			if (!$viewer) {
				return sprintf('<p class="dmError">Unable to render the object
					viewer; viewer class %s does not exist.</p>',
					$obj->getViewerClassName());
			}
			return $js ? $viewer->getHTMLTag() : $viewer->getHTMLTagNoJS();
		} catch (DMClassNotFoundException $e) {
			return "<!-- " . DMString::websafe($e->getMessage()) . " -->";
		}
	}

}

